<template>
  <div class="content-wrap missdata-wrapper">
    <div class="content-box">
      <div :class="{ 'content-left w0': collapseIconLeft, 'content-left': !collapseIconLeft }">
        <div class="top-box">
          <Card>
            <div slot="title" class="tit clearfix">
              <div class="fl">全表缺失数据统计直方图</div>
              <a class="fr" v-show="showBarlineReturn" @click.prevent.stop="barlineReturnHandle"
                ><Icon type="ios-undo" />&nbsp;返回</a
              >
            </div>
            <div class="bar-line-box">
              <h-bar3d :defaultOptions="hBar3dOptions" :fetchData="getBarLineData" :chartData="seriesData" />
              <div class="total-num">总缺失表数:{{ meterTotal }}只</div>
              <Spin fix v-show="hBarLoading">数据加载中...</Spin>
            </div>
          </Card>
        </div>
        <div class="bottom-box">
          <Card>
            <div slot="title" class="tit">全表30天缺失数据折线图</div>
            <div class="bar-line-box">
              <h-line :fetchData="getSdData" :chartData="sdData" :defaultOptions="hLineOptions" />
              <Spin fix v-show="sdLoading">数据加载中...</Spin>
            </div>
          </Card>
        </div>
      </div>
      <div :class="centerClass">
        <Card>
          <div slot="title" class="filter-wrapper">
            <div class="collapse-left-icon collapse-icon" @click="collapseHandler('left')">
              <span v-if="collapseIconLeft" title="缩小">
                <Icon type="icon iconfont icon-xianghou" />
              </span>
              <span v-else title="放大">
                <Icon type="icon iconfont icon-xiangqian" />
              </span>
            </div>
            <Form slot="search-bar" inline ref="formCustom" style="text-align: center">
              <FormItem style="width:120px;margin-right:30px">
                <DatePicker
                  @on-change="changeCurrentDate"
                  type="date"
                  format="yyyy-MM-dd"
                  placeholder="选择日期"
                  size="small"
                ></DatePicker>
              </FormItem>
              <FormItem>
                <Dropdown class="params-info" trigger="custom" :visible="paramsFlag">
                  <Button type="info" @click="handleParams(true)" size="small">筛选条件</Button>
                  <DropdownMenu slot="list" class="fb" style="width:400px">
                    <DropdownItem>
                      <div class="name">点半径</div>
                      <div class="slider">
                        <Slider :min="1" :max="10" v-model="pointRadius"></Slider>
                      </div>
                      <span class="show-num">x {{ pointRadius }}</span>
                    </DropdownItem>
                    <DropdownItem>
                      <div class="name">缺失条数</div>
                      <div class="slider">
                        <Slider :min="0" :max="48" v-model="qsNum"></Slider>
                      </div>
                      <span class="show-num">x {{ qsNum }}</span>
                    </DropdownItem>
                    <div style="text-align: right;margin-right:16px;">
                      <Button type="primary" @click="handleParams(false)" size="small">关闭</Button>
                    </div>
                  </DropdownMenu>
                </Dropdown>
              </FormItem>
              <FormItem>
                <Button type="primary" @click="handleShowTableClick" size="small">获取数据表格</Button>
              </FormItem>
            </Form>
            <div class="collapse-right-icon collapse-icon" @click="collapseHandler('right')">
              <span v-if="collapseIconRight" title="缩小">
                <Icon type="icon iconfont icon-xiangqian" />
              </span>
              <span v-else title="放大">
                <Icon type="icon iconfont icon-xianghou" />
              </span>
            </div>
          </div>
          <div class="chart-container">
            <div class="chart" key="effectScatter">
              <e-heatmap
                id="missingDataScatterMap"
                :fetchData="getEffectScatterData"
                :chartData="eHeatmapData"
                :shrink="collapseIcon"
                @q-click="pointClickHandle"
              />
              <Spin fix v-show="eHeatmapLoading">地图规划中...</Spin>
            </div>
          </div>
        </Card>
      </div>
      <div :class="{ 'content-right w0': collapseIconRight, 'content-right': !collapseIconRight }">
        <div class="top-box">
          <Card>
            <div slot="title" class="tit">缺失数据仪表图</div>
            <div class="bar-line-box">
              <h-gauge :chartData="solidGaugeData" :defaultOptions="hGaugeOptions" />
              <Spin fix v-show="solidGaugeLoading">数据加载中...</Spin>
            </div>
          </Card>
        </div>
        <div class="top-box">
          <Card>
            <div slot="title" class="tit">缺失日历</div>
            <div class="bar-line-box">
              <e-calendar :chartData="rlData" @q-click="reactHeatMapPointClick" />
              <Spin fix v-show="rlLoading">数据加载中...</Spin>
            </div>
          </Card>
        </div>
        <div :class="'bottom-box detail-wrap ' + collapseClass">
          <Collapse accordion simple @on-change="handlChangeCollapse">
            <Panel name="1">
              <span>详情</span>
              <div slot="content" style="height:100%;width:100%;">
                <div class="detail-box">
                  <meter-detail
                    :currentMeterId="currentMeterId"
                    :content="meterDetail"
                    :columnNames="meterDetailColumns"
                    :currentDate="currentDate"
                  />
                </div>
              </div>
            </Panel>
          </Collapse>
        </div>
      </div>
    </div>
    <!-- 表格下载 -->
    <Modal
      v-model="showDownTable"
      class="candlestick-modal"
      title="表格"
      width="96%"
      :styles="{ top: '30px'}"
    >
      <down-table v-if="showDownTable" :options="downTableOptions" />
    </Modal>
  </div>
</template>
<script>
import { each, max, reduce, min, merge, isNaN } from 'lodash'
import dayjs from 'dayjs'
import { barLine, mapList, sd, meterDetail, deficiency } from '@/api/meterManageMissingData'
import { hLineOptions, hBar3dOptions, eCalendarOptions, hGaugeOptions, eHeatmapOptions } from './chartOptions'
import DownTable from './components/DownTable'
import meterDetailColumns from './meterDetailColumns'

export default {
  name: 'cycle',
  components: {
    DownTable,
    MeterDetail: () => import('@/commons/MeterDetail'),
    EHeatmap: () => import('@/commons/charts/EHeatmap'),
    HBar3d: () => import('@/commons/charts/HBar3d'),
    HLine: () => import('@/commons/charts/HLine'),
    HGauge: () => import('@/commons/charts/HGauge'),
    ECalendar: () => import('@/commons/charts/ECalendar')
  },
  data() {
    return {
      currentTime: this.$config.nowDate,
      centerPoint: null,
      showBarlineReturn: false,
      paramsFlag: false,
      saveBtnLoading: false,
      chartsFlag: false,
      collapseIcon: false,
      collapseIconLeft: false,
      collapseIconRight: false,
      seriesData: null,
      eHeatmapData: null,
      eHeatmapList: null,
      sdData: null,
      pointRadius: 2,
      pointRadiusBak: 2,
      meterDetail: {},
      currentMeterId: undefined,
      solidGaugeData: null,
      rlData: null,
      rlDaysData: null,
      showDetailLoading: false,
      zhuzhuangtDataBak: null,
      meterTotal: 0,
      collapseState: false,
      qsNum: 0,
      qsNumBak: 0,
      eHeatmapLoading: false,
      solidGaugeLoading: false,
      rlLoading: false,
      hBarLoading: false,
      sdLoading: false,
      showDownTable: false,
      downTableOptions: {}
    }
  },
  mounted() {
    this.centerPoint = this.$store.getters.mapCenter
    this.sliderListerMouseUp()
  },
  computed: {
    defaultDate() {
      return this.$config.nowDate
    },
    /**
     * @msg: 当前日期
     * @param {type}
     * @return:
     */
    currentDate() {
      return dayjs(this.defaultDate).format('YYYY-MM')
    },
    hBar3dOptions() {
      return hBar3dOptions
    },
    hLineOptions() {
      return hLineOptions
    },
    hGaugeOptions() {
      return hGaugeOptions
    },
    meterDetailColumns() {
      return meterDetailColumns
    },
    collapseClass() {
      return this.collapseState ? 'collapse-avtive' : ''
    },
    centerClass() {
      let _cls = 'content-center'
      if (this.collapseIconLeft) {
        _cls += ' l0'
      }
      if (this.collapseIconRight) {
        _cls += ' r0'
      }
      return _cls
    }
  },
  beforeDestroy() {
    document.removeEventListener('mouseup', this.handleMouseUp)
  },
  methods: {
    /**
     * @msg: 日期改变
     * @param {date}
     * @return:
     */
    changeCurrentDate(date) {
      this.currentTime = date || this.defaultDate
      this.getEffectScatterData()
      this.getSdData()
      this.solidGaugeData = null
      this.rlData = null
      this.rlDaysData = []
    },
    /**
     * 两侧菜单收缩
     * @return {[type]} [description]
     */
    collapseHandler(direc) {
      const { collapseIconLeft, collapseIconRight, collapseIcon } = this
      if (direc === 'left') {
        this.collapseIconLeft = !collapseIconLeft
      } else {
        this.collapseIconRight = !collapseIconRight
      }
      this.collapseIcon = !collapseIcon
    },
    /**
     * 整理柱状图数据
     * @param  {[type]} data [description]
     * @return {[type]}      [description]
     */
    modifyBarLineData(data = []) {
      const _this = this
      const _xAxisList = []
      const _serList = []
      each(data, (item, index) => {
        const { count, minDeficiency, maxDeficiency } = item
        _xAxisList.push(index)
        _serList.push({
          name: minDeficiency + '-' + maxDeficiency,
          y: count,
          minDeficiency,
          maxDeficiency
        })
      })

      this.meterTotal = reduce(
        _serList,
        (sum, item) => {
          return sum + item.y
        },
        0
      )

      this.seriesData = merge({}, hBar3dOptions, {
        plotOptions: {
          series: {
            cursor: 'pointer',
            events: {
              click: function(e) {
                _this.barLineClickHandle(e, this)
              }
            }
          }
        },
        xAxis: {
          categories: _xAxisList
        },
        series: [
          {
            data: _serList
          }
        ]
      })
    },
    getMax(data = []) {
      const yArr = []
      each(data, item => {
        yArr.push(item.y)
      })
      const yMax = max(yArr)
      const yMin = min(yArr)
      return {
        yMax,
        yMin
      }
    },
    /**
     * 整理散点图数据
     * @param  {[type]} data [description]
     * @return {[type]}      [description]
     */
    modifySdData(data = []) {
      const _list = []
      each(data, (item, index) => {
        const { deficiency, tId } = item
        _list.push({
          name: tId,
          y: deficiency
        })
      })
      const { yMax = 0, yMin = 0 } = this.getMax(_list)
      const _chartData = merge({}, hLineOptions, {
        yAxis: {
          min: yMin,
          max: yMax
        },
        series: [
          {
            name: '',
            data: _list
          }
        ]
      })

      this.sdData = _chartData
    },
    /**
     * 整理地图数据
     * @param  {[type]} data [description]
     * @return {[type]}      [description]
     */
    modifyEffectScatterData(data = []) {
      const _this = this
      const _serList = []
      each(data, item => {
        const { meterId, deficiency, latitude, longitude } = item
        if (deficiency >= this.qsNum) {
          _serList.push({
            name: meterId,
            value: [longitude, latitude, deficiency]
          })
        }
      })
      this.eHeatmapData = merge({}, eHeatmapOptions, {
        bmap: {
          center: this.centerPoint
        },
        series: [
          {
            data: _serList,
            symbolSize: function(val = []) {
              const _num = isNaN(parseInt(val[2])) ? 0 : val[2]
              return _num / 5 * _this.pointRadius
            }
          }
        ]
      })
    },
    /**
     * @msg: 处理热力图数据
     * @param {data}
     * @return:
     */
    modifyDeficiencyData(data = []) {
      const _seriesData1 = []
      const _seriesData2 = []
      each(data, (item, index) => {
        const { deficiency, tId } = item
        _seriesData2.push([tId, deficiency])
        _seriesData1.push([tId, Number(index) + 1])
      })

      this.rlData = merge({}, eCalendarOptions, {
        calendar: [
          {
            range: this.currentTime ? dayjs(this.currentTime).format('YYYY-MM') : ''
          }
        ],
        series: [
          {
            type: 'scatter',
            coordinateSystem: 'calendar',
            symbolSize: 1,
            label: {
              show: true,
              color: '#fff',
              position: 'insideBottomRight'
            },
            data: _seriesData1
          },
          {
            label: {
              show: false,
              color: '#fff'
            },
            type: 'scatter',
            coordinateSystem: 'calendar',
            data: _seriesData2,
            symbolSize: function(val) {
              const ret = Math.log(val[1] + 1).toFixed(2)
              return ret * 4
            },
            zlevel: 3
          }
        ]
      })
    },
    /**
     * @msg: 滑动条绑定鼠标松开事件
     * @param {type}
     * @return:
     */
    sliderListerMouseUp() {
      document.addEventListener('mouseup', this.handleMouseUp)
    },
    handleMouseUp() {
      if ((Number(this.pointRadius) !== Number(this.pointRadiusBak)) || Number(this.qsNum) !== Number(this.qsNumBak)) {
        this.pointRadiusBak = this.pointRadius
        this.qsNumBak = this.qsNum
        this.modifyEffectScatterData(this.eHeatmapList)
      }
    },
    /**
     * 点击参数设置
     * @param  {[type]} flag [description]
     * @return {[type]}      [description]
     */
    handleParams(flag) {
      this.paramsFlag = flag
    },
    /**
     * 获取柱状图数据
     * @return {[type]} [description]
     */
    getBarLineData() {
      const retDate = this.currentTime || this.defaultDate

      this.fetchBarLineData({
        tId: retDate
      })
    },
    /**
     * @msg: 请求柱状图数据
     * @param {type}
     * @return:
     */
    async fetchBarLineData(params, flag) {
      this.hBarLoading = true
      const { code, date } = await barLine(params)
      this.hBarLoading = false
      if (code === 200) {
        this.modifyBarLineData(date)
        if (!flag) {
          this.zhuzhuangtDataBak = date
        } else {
          this.showBarlineReturn = true
        }
      }
    },
    /**
     * @msg: 获取地图信息数据
     * @param {type}
     * @return:
     */
    async getEffectScatterData() {
      this.eHeatmapLoading = true
      const tId = this.currentTime || this.defaultDate
      const { code, date } = await mapList({
        tId
      })
      this.eHeatmapLoading = false
      if (code === 200) {
        this.eHeatmapList = date
        this.modifyEffectScatterData(date)
      }
    },
    /**
     * 获取散点图数据
     * @return {[type]} [description]
     */
    async getSdData() {
      this.sdLoading = true
      let dateMonth = this.currentTime || this.defaultDate
      dateMonth = dayjs(dateMonth).format('YYYY-MM-DD')
      const { code, date } = await sd({
        dateMonth
      })
      this.sdLoading = false
      if (code === 200) {
        this.modifySdData(date)
      }
    },
    /**
     * @msg: 获取表具详情
     * @param {meterId} 表具id
     * @return:
     */
    async getMeterDetail(meterId, tId) {
      this.solidGaugeLoading = true
      const { code, date } = await meterDetail({
        meterId,
        tId
      })
      this.solidGaugeLoading = false
      if (code === 200) {
        this.meterDetail = date
        const { actual, plan } = date
        let planNum = plan > 1000 ? 100 : 10
        this.solidGaugeData = merge({}, hGaugeOptions, {
          yAxis: {
            softMax: plan,
            plotBands: {
              from: plan - planNum,
              to: plan
            }
          },
          series: [
            {
              data: [
                {
                  y: actual,
                  max: plan
                }
              ]
            }
          ]
        })
      }
    },
    /**
     * @msg:热力图数据获取
     * @param {meterId}
     * @return:
     */
    async getDeficiency(meterId) {
      this.rlLoading = true
      let dateMonth = this.currentTime || this.defaultDate
      dateMonth = dayjs(dateMonth).format('YYYY-MM')
      const { code, date } = await deficiency({
        dateMonth,
        meterId
      })
      this.rlLoading = false
      if (code === 200) {
        this.modifyDeficiencyData(date)
      }
    },
    /**
     * @msg: 散点图表具点点击
     * @param {type}
     * @return:
     */
    pointClickHandle(data = {}) {
      const { name } = data
      if (name) {
        const tId = this.currentTime || this.defaultDate
        this.currentMeterId = name
        this.getMeterDetail(name, tId)
        this.getDeficiency(name)
      }
    },
    reactHeatMapPointClick(data) {
      this.getMeterDetail(this.currentMeterId, data.value[0])
    },
    /**
     * @msg: 柱状图点击
     * @param {type}
     * @return:
     */
    barLineClickHandle(data = {}) {
      const { options } = data.point
      const { minDeficiency, maxDeficiency } = options
      const retDate = this.currentTime || this.defaultDate
      this.fetchBarLineData(
        {
          tId: retDate,
          minDeficiency,
          maxDeficiency
        },
        true
      )
    },
    /**
     * @msg: 柱状图标题点击范围
     * @param {type}
     * @return:
     */
    barlineReturnHandle() {
      this.showBarlineReturn = false
      this.modifyBarLineData(this.zhuzhuangtDataBak)
    },
    handlChangeCollapse(params) {
      if (params.length > 0) {
        this.collapseState = true
      } else {
        this.collapseState = false
      }
    },
    handleShowTableClick() {
      this.handleParams(false)
      this.downTableOptions.tId = this.currentTime
      this.downTableOptions.deficiency = this.qsNum
      this.showDownTable = true
    }
  }
}
</script>
<style scoped lang="less">
@import './index.less';
</style>
